package main

import (
	"fmt"
	"reflect"
)

//可以用反射提取struct tag，还能自动分解。其常用于ORM映射，或数据格式验证

type user struct {
	name string `field:"name" type:"varchar(50)"`
	age  int    `field:"age" type:"int"`
}

type X int

func (X) String() string  {
	return ""
}
func main() {
	var u user
	t := reflect.TypeOf(u)
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		fmt.Printf("%s:%s %s\n", f.Name, f.Tag.Get("field"), f.Tag.Get("type"))
	}
	//辅助判断方法 Implements，ConvertibleTo，AssignableTo 都是运行期间进行动态调用和赋值所必须的
	fmt.Println("---------------------")

	var a X
	t1 := reflect.TypeOf(a)
	//Implements 不能直接使用类型作为参数
	st := reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
	fmt.Println(t1.Implements(st))

	it := reflect.TypeOf(0)
	fmt.Println(t1.ConvertibleTo(it))

	fmt.Println(t1.AssignableTo(st),t1.AssignableTo(it))
}
